import time
import logging
import pyautogui
import cv2
import os
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from webdriver_manager.chrome import ChromeDriverManager
from selenium.common.exceptions import TimeoutException, NoSuchElementException
import platform
import undetected_chromedriver as uc

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler("baidu_upload.log"),
        logging.StreamHandler()
    ]
)
logger = logging.getLogger(__name__)

# 获取屏幕上的坐标
def get_xy(image_path):
    # Create the pic directory if it doesn't exist
    if not os.path.exists('./pic'):
        os.makedirs('./pic')
    
    # Take a screenshot and save it
    pyautogui.screenshot().save('./pic/screenshot.png')
    
    # Load the template image
    template = cv2.imread(image_path)
    if template is None:
        print(f"Error: Could not load template image from {image_path}")
        return None
    
    # Load the screenshot
    screenshot = cv2.imread('./pic/screenshot.png')
    
    # Convert images to grayscale
    template_gray = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    screenshot_gray = cv2.cvtColor(screenshot, cv2.COLOR_BGR2GRAY)
    
    # Perform template matching
    result = cv2.matchTemplate(screenshot_gray, template_gray, cv2.TM_CCOEFF_NORMED)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
    
    # If the match is good enough
    if max_val > 0.8:
        # Get the center of the matched area
        h, w = template.shape[:2]
        center_x = max_loc[0] + w // 2
        center_y = max_loc[1] + h // 2
        return (center_x, center_y)
    else:
        print(f"No good match found. Best match: {max_val}")
        return None

# 配置 ChromeOptions
def create_chrome_driver():
    options = uc.ChromeOptions()
    user_data_dir = f"C:/Users/vaan/AppData/Local/Google/Chrome/User Data"
    profile_directory = "Default"
    options.add_argument(f"--user-data-dir={user_data_dir}")
    options.add_argument(f"--profile-directory={profile_directory}")
    options.add_argument("--start-maximized")
    options.add_argument("--disable-gpu")
    options.add_argument('--disable-software-rasterizer')
    options.add_argument('--disable-extensions')
    
    # 使用 undetected_chromedriver 创建驱动
    driver = uc.Chrome(options=options)
    return driver

# 封装上传过程
def click_image_button(template_path, error_message="未找到目标按钮"):
    """
    识别并点击图片按钮
    :param template_path: 模板图片路径
    :param error_message: 未找到按钮时的错误信息
    :return: bool 点击是否成功
    """
    coordinates = get_xy(template_path)
    if not coordinates:
        logger.error(error_message)
        return False
    
    pyautogui.moveTo(coordinates[0], coordinates[1])
    pyautogui.click()
    return True

# 在 /documentation页面的函数
def documentation_page_handler(driver, wait, file_path):
    try:
        # 点击上传按钮
        upload_button = wait.until(EC.element_to_be_clickable((
            By.XPATH, "//*[@id='upload-doc']"
        )))
        upload_button.click()
        time.sleep(2)

        # 点击文件上传按钮
        template_path = "./pic/file_uplaod_template.jpg"
        if not click_image_button(template_path, "未找到文件上传按钮"):
            return False

        # 输入文件路径
        if platform.system() == 'Darwin':
            pyautogui.write(file_path)
        else:
            try:
                import pyperclip
                pyperclip.copy(file_path)
                pyautogui.hotkey('ctrl', 'v')
            except ImportError:
                logger.error("请安装pyperclip: pip install pyperclip")
                pyautogui.write(file_path)

        # 点击打开按钮
        template_path_open_btn = "./pic/open_btn.jpg"
        if not click_image_button(template_path_open_btn, "未找到打开按钮"):
            return False
        
        return True

    except Exception as e:
        logger.error(f"文件上传过程出错: {str(e)}")
        return False
# 处理/doc/upload页面的函数
def upload_page_handler(driver, title, description):
    """
    填写表单信息
    :param driver: WebDriver实例
    :param title: 标题
    :param description: 描述
    :return: bool 表单填写是否成功
    """
    try:
        # 填写标题
        title_input = driver.find_element(By.XPATH,'//*[@id="app"]/div[1]/section/main/div[1]/div/div[3]/div[1]/div[1]/div[1]/div/form/div/div/div/div[1]/input')
        title_input.clear()
        title_input.send_keys(title)
        logger.info(f"已填写标题: {title}")

        # 填写简介
        description_input = driver.find_element(By.XPATH, '//*[@id="app"]/div[1]/section/main/div[1]/div/div[3]/div[1]/div[1]/form/div[3]/div/div/div/div/textarea')
        description_input.clear()
        description_input.send_keys(description)
        logger.info(f"已填写简介: {description}")

        # 选择VIP收益类型
        income_type_vip = driver.find_element(By.XPATH, "//label[contains(., 'VIP') or contains(., 'vip')]")
        income_type_vip.click()
        logger.info("已选择VIP收益类型")

        # 提交表单
        submit_button = driver.find_element(By.XPATH, "//button[contains(., '提交') or contains(., 'submit')]")
        time.sleep(2)
        submit_button.click()
        logger.info("已点击提交按钮")
    except Exception as e:
        logger.error(f"表单填写失败: {str(e)}")
        return False
    finally:
        return click_image_button("pic/upload_ready.jpg", "未找到提交按钮")
# 在upload_files方法中使用这个新函数
def upload_files(param_maps):
    driver = create_chrome_driver()
    wait = WebDriverWait(driver, 30)

    try:
        for index, param_map in enumerate(param_maps):
            file_path = param_map['file_path']
            title = param_map['title']
            description = param_map['description']
            
            logger.info(f"开始处理第 {index+1}/{len(param_maps)} 个文件: {file_path}")
            
            timestamp = int(time.time() * 1000)
            upload_url = f'https://cuttlefish.baidu.com/shopmis?fr=index2023&_wkts_={timestamp}#/commodityManage/documentation'
            driver.get(upload_url)

            # 检查当前URL是否匹配预期URL
            while True:
                current_url = driver.current_url
                #如果current_url 中包含 /commodityManage/documentation则执行upload_file方法
                if '/commodityManage/documentation' in current_url:
                    documentation_page_handler(driver, wait, file_path)
                elif '/doc/upload' in current_url:
                    if upload_page_handler(driver, title, description):
                        logger.info("文件上传成功")
                        break
                else :
                    logger.info("当前URL不匹配预期URL，等待30秒后重试...")
                    time.sleep(10)
                    continue
                time.sleep(5)

    except Exception as e:
        logger.error(f"执行异常：{str(e)}")
        driver.save_screenshot("error.png")
    finally:
        try:
            driver.quit()
            logger.info("浏览器已关闭")
        except Exception as e:
            logger.error(f"关闭浏览器时出错: {str(e)}")


# 参数封装成一个包含多个字典的数组
param_maps = [
    {
        'file_path': r"E:\PycharmProjects\llamaindex_project\data\中药附子的详细介绍.docx",
        'title': "中药——附子详细介绍",
        'description': "这是一本关于附子的中药文件。"
    },
    {
        'file_path': r"E:\PycharmProjects\llamaindex_project\data\中药川芎的详细介绍.docx",
        'title': "中药——川芎详细介绍",
        'description': "这是一本关于川芎的中药文件。"
    }
]


if __name__ == "__main__":
    # 调用上传方法
    logger.info("开始上传文件任务")
    upload_files(param_maps)
    logger.info("上传文件任务完成")